import json
from jsonpath_ng import parse
from typing import Dict, Optional,Any
from utils.cache_tools.cache_control import CacheHandler
from utils.logging_tools.log_control import INFO,ERROR


class JsonPathExtractor:
    """处理 JSONPath 提取表达式的类，验证 JSON 字符串并将成功提取的值写入缓存"""

    @staticmethod
    def is_valid_json(data: str) -> bool:
        """
        检查输入字符串是否为有效 JSON 格式

        参数:
            data: 可能的 JSON 数据字符串

        返回:
            bool: 如果是有效 JSON 则返回 True，否则返回 False
        """
        try:
            json.loads(data)
            return True
        except json.JSONDecodeError:
            return False
    @classmethod
    def extract(cls, response_data: str, extract_rules: Dict[str,object]) -> None:
        """
        使用 JSONPath 表达式从响应数据中提取值，并将成功提取的值写入缓存

        参数:
            response_data: 响应数据的 JSON 字符串
            extract_rules: 变量名和对应的 JSONPath 表达式的字典

        返回:
            None
        """
        INFO.info("开始处理变量提取")
        if not extract_rules:
            INFO.info("未检测到jsonpath提取表达式，跳过变量提取！")
            return
        # 验证 JSON 格式
        if not cls.is_valid_json(response_data):
            raise ValueError("响应数据不是有效的 JSON 字符串")

        try:
            # 解析响应数据
            json_data = json.loads(response_data)

            # 处理每个提取规则
            for var_name, jsonpath_expr in extract_rules.items():
                try:
                    # 解析 JSONPath 表达式
                    jsonpath_parse = parse(jsonpath_expr)

                    # 查找匹配项
                    matches = jsonpath_parse.find(json_data)

                    # 如果有匹配项，保存第一个值并写入缓存
                    if matches:
                        value = matches[0].value
                        CacheHandler.set_string(var_name, value)
                        INFO.info(f"成功提取变量 '{var_name}': {value},已写入缓存")

                except Exception as e:
                    ERROR.error(f"处理 JSONPath '{jsonpath_expr}' 时出错，变量 '{var_name}': {str(e)}")
                    raise ValueError(f"处理 JSONPath '{jsonpath_expr}' 时出错，变量 '{var_name}': {str(e)}")
                    # 记录错误并继续处理下一个规则


        except json.JSONDecodeError as e:
            raise ValueError(f"解析 JSON 数据失败: {str(e)}")

